using MeetingManagement.Domain.Common;

namespace MeetingManagement.Domain.Entities
{
    public class MeetingRoom : AggregateRoot
    {
        public string Name { get; private set; }
        public string Location { get; private set; }
        public int Capacity { get; private set; }
        public bool HasProjector { get; private set; }
        public bool HasWhiteboard { get; private set; }
        public bool HasVideoConference { get; private set; }
        public string Description { get; private set; }
        public bool IsActive { get; private set; }

        public List<Meeting> Meetings { get; private set; } = new List<Meeting>();

        protected MeetingRoom()
        {
        }

        public static MeetingRoom Create(string name, string location, int capacity,
            bool hasProjector = false, bool hasWhiteboard = false,
            bool hasVideoConference = false, string description = null)
        {
            if (string.IsNullOrWhiteSpace(name))
                throw new ArgumentException("会议室名称不能为空", nameof(name));

            if (capacity <= 0)
                throw new ArgumentException("会议室容量必须大于0", nameof(capacity));

            return new MeetingRoom
            {
                Name = name,
                Location = location,
                Capacity = capacity,
                HasProjector = hasProjector,
                HasWhiteboard = hasWhiteboard,
                HasVideoConference = hasVideoConference,
                Description = description,
                IsActive = true
            };
        }


        public void Update(string name, string location, int capacity,
            bool hasProjector, bool hasWhiteboard, bool hasVideoConference, string description)
        {
            if (string.IsNullOrWhiteSpace(name))
                throw new ArgumentException("会议室名称不能为空", nameof(name));

            if (capacity <= 0)
                throw new ArgumentException("会议室容量必须大于0", nameof(capacity));

            Name = name;
            Location = location;
            Capacity = capacity;
            HasProjector = hasProjector;
            HasWhiteboard = hasWhiteboard;
            HasVideoConference = hasVideoConference;
            Description = description;
            UpdatedDate = DateTime.UtcNow;
        }


        public void ChangeName(string name)
        {
            if (string.IsNullOrWhiteSpace(name))
                throw new ArgumentException("会议室名称不能为空", nameof(name));

            Name = name;
            UpdatedDate = DateTime.UtcNow;
        }

        public void ChangeCapacity(int capacity)
        {
            if (capacity <= 0)
                throw new ArgumentException("会议室容量必须大于0", nameof(capacity));

            Capacity = capacity;
            UpdatedDate = DateTime.UtcNow;
        }

        public void SetFeatures(bool hasProjector, bool hasWhiteboard, bool hasVideoConference)
        {
            HasProjector = hasProjector;
            HasWhiteboard = hasWhiteboard;
            HasVideoConference = hasVideoConference;
            UpdatedDate = DateTime.UtcNow;
        }


        public void Activate()
        {
            if (IsActive) return;

            IsActive = true;
            UpdatedDate = DateTime.UtcNow;
        }

        public void Deactivate()
        {
            if (!IsActive) return;

            IsActive = false;
            UpdatedDate = DateTime.UtcNow;
        }


        public void AssignMeeting(Meeting meeting)
        {
            if (meeting == null)
                throw new ArgumentNullException(nameof(meeting));

            if (!IsActive)
                throw new InvalidOperationException("不能在非活跃会议室安排会议");

            if (!Meetings.Contains(meeting))
            {
                Meetings.Add(meeting);
                meeting.AssignMeetingRoom(this);
                UpdatedDate = DateTime.UtcNow;
            }
        }


        public bool CanAccommodate(int requiredCapacity)
        {
            return IsActive && Capacity >= requiredCapacity;
        }

        public bool IsAvailableAt(DateTime startTime, DateTime endTime)
        {
            if (!IsActive)
                return false;

            foreach (var meeting in Meetings)
            {

                if (meeting.Status == MeetingStatus.Cancelled)
                    continue;


                if (meeting.GetStartTime() < endTime && startTime < meeting.GetEndTime())
                    return false;
            }

            return true;
        }
    }
}
